<?php
	require_once("htons-ntohs.php");
	require_once("protocoldef.php");

	// 格式:uint64|uint|uint64
	//// 适用于记录评论(rcmt)、图片评论(pcmt)、转发feed(ftrans)
	class InsertCmd{
	 public $cmd	= array(
		"msg_id" => array(
			"type" 	=> "uint64",
			"value" => 0,
			"repeat" => 0),
		"create_time" => array(
			"type"  => "uint32",
			"value" => 0,
			"repeat" => 0),
		"cmt_id" => array(
			"type"  => "uint64",
			"value" => 0,
			"repeat" => 1),
		"end"	 => array(
			"type"  => "char",
			"value" => 3,
			"repeat" => 0)
		);
	}

	//error_reporting(0);
	// 开始时间
	$start=microtime(true);

	$DBINFO=array(
		0 => array(	// mi 记录评论(rcmt)
			"mongoserver" => "10.10.83.7",
			"mongoport"   => 65431,
			"idxserver"   => "10.10.83.30",
			"idxport"     => 58000,
			"packlength"  => 37,
			"dbname" => "db2_mi_",
			"dbnum"  => 10,
			"tbname" => "t_mi_",
			"tbnum"  =>  1,
			"name"	 => "rcmt",
			"field"  => array(		
				0 => "msg_id",
				1 => "create_time",
				2 => "cmt_id"
			)
		),
		1 => array(	// pici 图片评论(pcmt)
			"mongoserver" => "10.10.83.7",
			"mongoport"   => 65431,
			"idxserver"   => "10.10.83.30",
			"idxport"     => 58001,
			"packlength"  => 37,
			"dbname" => "db2_pici_",
			"dbnum"  => 10,
			"tbname" => "t_pici_",
			"tbnum"  =>  1,
			"name"	 => "pcmt",
			"field"  => array(		
				0 => "photo_id",
				1 => "create_time",
				2 => "cmt_id"
			)
		),
		2 => array(	// tri 转发feed(ftrans)
			"mongoserver" => "10.10.83.7",
			"mongoport"   => 65431,
			"idxserver"   => "10.10.83.30",
			"idxport"     => 58006,
			"packlength"  => 37,
			"dbname" => "db2_tri_",
			"dbnum"  => 10,
			"tbname" => "t_tri_",
			"tbnum"  =>  1,
			"name"	 => "ftrans",
			"field"  => array(		
				0 => "target_id",
				1 => "create_time",
				2 => "msg_id"
			)
		)
	);

	// 重试次数
	define("RETRY",5);


	$totalrecord=1;
	foreach($DBINFO as $dbkey => $dbvalue)
	{
		$mongoserver	= $DBINFO[$dbkey]['mongoserver'];
		$mongoport	= $DBINFO[$dbkey]['mongoport'];
		$idxserver	= $DBINFO[$dbkey]['idxserver'];
		$idxport	= $DBINFO[$dbkey]['idxport'];
		$packlength	= $DBINFO[$dbkey]['packlength'];
		$dbnum		= $DBINFO[$dbkey]['dbnum'];
		$recordname	= $DBINFO[$dbkey]['name'];
		$recordnum	= 0;

		// 初始化头
		$uvheader=new UVHEADER();
		$uvheader->header["len"]["value"]	= $packlength;
		$uvheader->header["cmd"]["value"]	= 3;
		uvpack($uvheader->header);

		// 预先声明InsertCmd对象
		$insertcmd	= new InsertCmd();

		// 连接Mongo
		$server="mongodb://".$mongoserver.":".$mongoport;
		$conn=new Mongo($server);
		if($conn===false)
		{
			print "Mongo() fail<br />";
			exit(-1);
		}

		printf("mongodb: [%s:%s]\n",$mongoserver,$mongoport);

		// 与索引系统建立socket长连接
		$sockfd=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
		if($sockfd==false)
		{
			printf("socket_create fail.[%d-%s]<br />",socket_last_error(),socket_strerror(socket_last_error()));
			exit(-1);
		}

		if((socket_connect($sockfd,$idxserver,$idxport))==false)
		{
			printf("socket_connect fail.[%d-%s]<br />",socket_last_error(),socket_strerror(socket_last_error()));
			exit(-1);
		}
		
		printf("indexdb: [%s:%s]\n",$idxserver,$idxport);

		for($i=0;$i<$dbnum;$i++)
		{
			$dbname = $DBINFO[$dbkey]['dbname']."0_".$i;

			$db=$conn->selectDB($dbname);
			printf("dbname = %s dbnum = %d start:\n",$dbname,$i);

			// 获取三个索引字段的字段名称(msg_id,create_time,cmt_id)
			$key1	= $DBINFO[$dbkey]['field'][0];
			$key2	= $DBINFO[$dbkey]['field'][1];
			$key3	= $DBINFO[$dbkey]['field'][2];

			$tbnum=$DBINFO[$dbkey]['tbnum'];
			for($j=0;$j<$tbnum;$j++)
			{
				$tbname = $DBINFO[$dbkey]['tbname'].$j;

				$collect=$db->selectCollection($tbname);
				printf("tbname = %s tbnum = %d start:\n",$tbname,$j);
				
				$cursor=$collect->find();
				$num=1;
				foreach($cursor as $obj)
				{

					/////////////////// 此处的顺序一定不能错乱 /////////////////
					///// field字段名称的顺序，一定要按照【msg_id】、【create_time】、【user_id】的顺序进行填写，不能错乱 /////////////////////////////
					$insertcmd->cmd["msg_id"]["value"]			= $obj[$key1];
					$insertcmd->cmd["create_time"]["value"]		= $obj[$key2];
					$insertcmd->cmd["cmt_id"]["value"]			= $obj[$key3];
					printf("recordname = %s totalrecord = %u current num = %u %s = %lu %s = %u %s = %lu\n",$recordname,$totalrecord,$num,$key1,$obj[$key1],$key2,$obj[$key2],$key3,$obj[$key3]);
					$num++;
					$totalrecord++;
					$recordnum++;

					uvpack($insertcmd->cmd);

					// 头部格式及参数值
					$FORMAT	=	"CSSSC";
					$PARA[0]=	$uvheader->header["begin"]["value"];
					$PARA[1]=	$uvheader->header["len"]["value"];
					$PARA[2]=	$uvheader->header["ver"]["value"];
					$PARA[3]=	$uvheader->header["cmd"]["value"];
					$PARA[4]=	$uvheader->header["reserve"]["value"];
				
					// 判断列是否64位，如果是，则需要进行换位
					$flag		= 0;
					$addafter32	= "";
					$addbefore32	= "";
					foreach($insertcmd->cmd as $key => $value)
					{
						if(($key=="msg_id")||($key=="create_time")||($key=="cmt_id"))
						{
							$idtype=$insertcmd->cmd[$key]["type"];
							if($uvbyte[$idtype]==8)
							{	
								$temp1=decbin($insertcmd->cmd[$key]["value"]);
								$before32	= substr($temp1,0,-32);
								$after32	= substr($temp1,-32);
								$before32	= bindec($before32);
								$after32	= bindec($after32);
								$PARA[]		= $after32;
								$PARA[]		= $before32;
								$FORMAT		= $FORMAT."LL";	
								// 判断是否需要重复
								if($insertcmd->cmd[$key]["repeat"]==1)
								{
									$flag=1;
									$addafter32	= $after32;
									$addbefore32	= $before32;
								}
							}
							else
							{
								$PARA[]		= $insertcmd->cmd[$key]["value"];
								$FORMAT		= $FORMAT."L";	
							}
						}
					}

					if($flag==1)
					{
						$PARA[]	= $addafter32;
						$PARA[]	= $addbefore32;
						$FORMAT	= $FORMAT."LL";
					}

					
					$PARA[]	= $insertcmd->cmd["end"]["value"];
					$FORMAT	= $FORMAT."C";
					$temp=call_user_func_array("pack",array_merge((array)$FORMAT,$PARA));

					for($n = 0;$n < $packlength; $n++)
					//for($n = 0;$n < 29; $n++)
					{
						printf("%02x ",ord($temp[$n]));
						if(($n!=0)&&(($n+1)%8==0))
							printf("\n");

					}

					printf("\n");

		
					$buflen		= $packlength;
					$retry		= 1;
					$ret		= 0;
					while($retry<=RETRY)
					{
						$ret=socket_send($sockfd,$temp,$buflen,NULL);
						//$ret=socket_write($sockfd,$temp,$buflen);
						if($ret==$buflen)
						{
							break;
						}

						$retry++;
					}

					if($retry>RETRY)
					{
						printf("send data fail,sockfd = %s,totalrecord = %u,[%d-%s]\n",$sockfd,$totalrecord,socket_last_error(),socket_strerror(socket_last_error()));
						continue;
					}


					$temp="";
					$ret=socket_recv($sockfd,$temp,13,NULL);
					if(($ret===false)||($ret!==13))
					{
						printf("recv data fail,sockfd = %s,totalrecord = %u,[%d-%s]\n",$sockfd,$totalrecord,socket_last_error(),socket_strerror(socket_last_error()));
						continue;
					}

					$temp1=unpack("C/n/n/n/C/Ncode/C",$temp);
					if($temp["code"]!=0)
					{
						printf("unpack data fail,sockfd = %s,totalrecord = %u,[%d-%s]\n",$sockfd,$totalrecord,socket_last_error(),socket_strerror(socket_last_error()));
						continue;
					}	

					//if($totalrecord>=3)
					//	exit;

					unset($PARA);
					unset($FORMAT);

				} // foreach($cursor as $obj)
			} // for($j=0;$j<$tbnum;$j++)
			printf("\n");
		} // for($i=0;$i<$dbnum;$i++)
		socket_close($sockfd);
		$conn->close();
		printf("recordname = [%send],recordnum = [%lu]\n\n",$recordname,$recordnum);
	} // foreach($DBNAME as $dbkey => $dbvalue)
	

	echo "TOTAL TIME : ".(microtime(true)-$start)."\n\n";
?>
